package ink.xiaobaibai.units;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.lang3.time.DateUtils;

import java.util.Date;
import java.util.List;

/**
 * @description: JWT生成校验工具类
 * @author: 小白白
 * @create: 2021-05-14
 **/

public class JWTUnit {

    private static final String TOKEN_ASSERT = "wqr^et35as@asg$zx1$$vs";
    private static JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(TOKEN_ASSERT)).build();
    public static ThreadLocal<DecodedJWT> jwtThreadLocal = new ThreadLocal<>();

    /**
     * 根据用户账号和职位生成JWT
     */
    public static String getJWT(Integer userId, String userNumber, List<String> roleList) {
        Date nowDate = new Date();
        String token = JWT.create()
                .withAudience(userNumber)
                .withClaim("role", roleList)
                .withClaim("userId", userId)
                .withIssuedAt(nowDate)
                .withExpiresAt(DateUtils.addHours(nowDate, 24))
                .sign(Algorithm.HMAC256(TOKEN_ASSERT));
        return token;
    }

    /**
     * 校验JWT
     *
     * @param jwt
     * @return 当前JWT代表的角色集合
     */
    public static List<String> validJWT(String jwt) {
        DecodedJWT decodedJWT;
        try {
            decodedJWT = jwtVerifier.verify(jwt);
        } catch (Exception e) {
            return null;
        }
        jwtThreadLocal.set(decodedJWT);
        return decodedJWT.getClaim("role").asList(String.class);
    }

    public static String updateJWT(Integer userId) {
        DecodedJWT decodedJWT = jwtThreadLocal.get();
        jwtThreadLocal.remove();//立即remove
        //非空才去检验更新
        if (decodedJWT != null) {
            //获取失效时间
            Date expiresAt = decodedJWT.getExpiresAt();
            if (expiresAt.getTime() < DateUtils.addHours(new Date(), 8).getTime()) {
                //不到八小时就过期了,就更新一下jwt
                String userNumber = decodedJWT.getAudience().get(0);
                List<String> roleList = decodedJWT.getClaim("role").asList(String.class);
                return getJWT(userId, userNumber, roleList);
            }
        }
        return null;
    }

}
